package com.example.smartlearning.service.impl;


import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.example.smartlearning.dao.AccountDao;
import com.example.smartlearning.dao.UserDao;
import com.example.smartlearning.entity.AccountEntity;
import com.example.smartlearning.entity.ResultEntity;
import com.example.smartlearning.entity.UserEntity;
import com.example.smartlearning.service.UserService;
import com.example.smartlearning.tool.IpUtil;
import com.example.smartlearning.tool.Levenshtein;
import com.example.smartlearning.tool.MD5Tool;
import jakarta.annotation.Resource;
import jakarta.servlet.http.HttpServletRequest;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Service;


@Service
public class UserServiceImpl extends ServiceImpl<UserDao, UserEntity> implements UserService {

    private static final Logger logger = LoggerFactory.getLogger(UserServiceImpl.class);//日志。getLogger需要传入当前的类名

    @Resource
    AccountDao accountDao;
    @Resource
    UserDao userDao;
    @Resource
    MD5Tool md5Tool;
    @Resource
    IpUtil ipUtil;
    @Resource
    Levenshtein levenshtein;


    /**
     * 登录接口
     *
     * @param account 账号
     * @param pwd     密码
     * @return 返回
     */
    @Override
    public String logic(String account, String pwd, HttpServletRequest request) {
        try {
            AccountEntity accountMessage = accountDao.selectAccount(account);//通过账号查询去获取
            if (accountMessage == null) {
                return ResultEntity.loginFail(-10004);//当查询结果为空的时候直接返回错误信息
            }
            int userId = accountMessage.getUserId();//获取用户id
            if (account.contains("@")) {
                //表示为邮箱登录
                String EmailPwd = accountMessage.getAccountEmailPwd();//获取手机号登录密码
                System.out.println(md5Tool.ToMD5(pwd));
                if (EmailPwd.equals(md5Tool.ToMD5(pwd))) {
                    //表示密码正确 通过验证
                    //根据userid获取用户信息 并返回用户信息
                    UserEntity userEntity = userDao.selectById(userId);
                    String ip = ipUtil.getIpAddr(request);
//                    System.out.println(ip);
//                    System.out.println("密码正确");
                    if (ip.equals(userEntity.getUserLoginAddress())) {
                        //判断本地登录ip与上次是不是一致
                        return ResultEntity.success(userEntity);
                    } else {
                        userDao.updateIp(userId, ip);
                        return ResultEntity.login(userEntity);//登录地址发生改变
                    }
                } else {
                    //表示密码错误 返回错误信息
                    return ResultEntity.loginFail(-10005);//当查询结果为空的时候直接返回错误信息
                }
            } else {
                //表示为手机号登录
                String phonePwd = accountMessage.getAccountPhonePwd();//获取手机号登录密码
                if (phonePwd.equals(md5Tool.ToMD5(pwd))) {
                    //表示密码正确 通过验证
                    //根据userid获取用户信息 并返回用户信息
                    UserEntity userEntity = userDao.selectById(userId);
                    String ip = ipUtil.getIpAddr(request);
                    System.out.println(ip);
                    System.out.println("密码正确");
                    if (ip.equals(userEntity.getUserLoginAddress())) {
                        //判断本地登录ip与上次是不是一致
                        return ResultEntity.success(userEntity);
                    } else {
                        userDao.updateIp(userId, ip);
                        return ResultEntity.login(userEntity);//登录地址发生改变
                    }
                } else {
                    //表示密码错误 返回错误信息
                    return ResultEntity.loginFail(-10005);//当查询结果为空的时候直接返回错误信息
                }
            }
        } catch (Exception e) {
            e.printStackTrace();
            logger.error(e.getLocalizedMessage());
            return ResultEntity.fail(-10004);
        }
    }

    /**
     * 用户注册接口
     *
     * @param account 账号
     * @param pwd     密码
     * @return 返回
     */
    @Override
    public String register(String account, String pwd) {
        try {
            //查询该账号是不是已经被注册了 如果被注册就返回请登录
            UserEntity userEntity = userDao.selectByAccount(account);//通过账号查询去获取
            if (userEntity != null) {
                return ResultEntity.loginFail(-10007);//当查询结果不为空的时候直接返回错误信息
            }
            //该账号目前未被使用过 进入注册流程 调用注册的dao接口
            pwd = md5Tool.ToMD5(pwd);
            return ResultEntity.registerSuccess(accountDao.addAccount(account, pwd));
        } catch (Exception e) {
            e.printStackTrace();
            logger.error(e.getLocalizedMessage());
            return ResultEntity.fail(-10004);
        }
    }

    /**
     * 根据id更换用户信息
     *
     * @param userId   用户id
     * @param nickName 名称
     * @param number   学号
     * @param avatar   头像
     * @param email    邮箱
     * @param interest 兴趣
     * @param grade    年级
     * @return String
     */
    @Override
    public String updateUser(int userId, String nickName, String number, String avatar, String email, String phone, String interest, int grade, HttpServletRequest request) {
        try {
            if (userDao.selectByUserNickName(nickName) != 0) {//查询数据库中是不是已经有这个昵称了
                return ResultEntity.loginFail(-10008);//表示昵称重复
            }
            String loginAddress = ipUtil.getIpAddr(request);//查询用户当前的登录ip
            //手机号或邮箱为默认不允许更改 当用户更改的时候
            return ResultEntity.success(userDao.updateUserByUserId(userId, loginAddress, nickName, number, avatar, email, phone, interest, grade));

        } catch (Exception e) {
            e.printStackTrace();
            logger.error(e.getLocalizedMessage());
            return ResultEntity.fail(-10004);
        }
    }

    /**
     * 修改密码接口
     *
     * @param account 账号
     * @param pwd     密码
     * @param newPwd  新的密码
     * @return String
     */
    @Override
    public String updatePwd(String account, String pwd, String newPwd) {
        try {

            //先判断旧密码是不是正确
            String temp = accountDao.selectPwd(account);
            if (md5Tool.ToMD5(pwd).equals(temp)) {
                //密码正确
                //对旧密码以及新密码进行相似度验证
                String similar = levenshtein.levenshtein(pwd, newPwd);//获取两次密码的相似程度
                Float similars = Float.parseFloat(similar);//将String转化为float形式
                if (similars > 66.6) {
                    return ResultEntity.loginFail(-10009);//密码过于相似
                } else {
                    newPwd = md5Tool.ToMD5(newPwd);//转化为md5格式
                    return ResultEntity.success(accountDao.updatePwd(account, newPwd));//对数据进行操作
                }
            } else {
                return ResultEntity.loginFail(-10005);
            }
        } catch (Exception e) {
            e.printStackTrace();
            logger.error(e.getLocalizedMessage());
            return ResultEntity.fail(-10004);
        }
    }

    /**
     * 查询用户喜欢列表
     *
     * @param userId 用户id
     * @return String
     */
    @Override
    public String getUpvoteList(int userId, int start, int limit) {

        try {
            return ResultEntity.success(userDao.selectUpvote(userId, start, limit));
        } catch (Exception e) {
            e.printStackTrace();
            logger.error(e.getLocalizedMessage());
            return ResultEntity.fail(-10004);
        }
    }

    /**
     * 用户开通vip
     *
     * @param userId 用户id
     * @return 返回
     */
    @Override
    public String liberalVip(int userId) {
        try {
            return ResultEntity.success(userDao.liberalVip(userId));
        } catch (Exception e) {
            e.printStackTrace();
            logger.error(e.getLocalizedMessage());
            return ResultEntity.fail(-10004);
        }
    }

    /**
     * 传入用户id和头像地址
     *
     * @param userId 用户id
     * @param avatar 头像地址
     * @return 返回
     */
    @Override
    public String updateUserAvatarInt(int userId, String avatar) {
        try {
            return ResultEntity.success(userDao.updateUserAvatarInt(userId, avatar));
        } catch (Exception e) {
            e.printStackTrace();
            logger.error(e.getLocalizedMessage());
            return ResultEntity.fail(-10004);
        }
    }

    /**
     * 加分
     *
     * @param userId 用户id
     * @param points 加的分值
     * @return 返回
     */
    @Override
    public String updateUserPointsAdd(int userId, int points) {
        try {
            return ResultEntity.success(userDao.updateUserPointsAdd(userId, points));
        } catch (Exception e) {
            e.printStackTrace();
            logger.error(e.getLocalizedMessage());
            return ResultEntity.fail(-10004);
        }
    }

    /**
     * 用户扣除积分
     *
     * @param userId 用户id
     * @param points 扣除的分数
     * @return 返回
     */
    @Override
    public String updateUserPointsDelete(int userId, int points) {
        try {
            return ResultEntity.success(userDao.updateUserPointsDelete(userId, points));
        } catch (Exception e) {
            e.printStackTrace();
            logger.error(e.getLocalizedMessage());
            return ResultEntity.fail(-10004);
        }
    }

    /**
     * 传入一个用户id
     * @param userId
     * @return
     */
    @Override
    public String  selectFace(String name) {
        try {
            return ResultEntity.success(userDao.selectFace(name));
        } catch (Exception e) {
            e.printStackTrace();
            logger.error(e.getLocalizedMessage());
            return ResultEntity.fail(-10004);
        }
    }

    @Override
    public String addFace(int userId,String name, String img) {
        try {
            return ResultEntity.success(userDao.addFace(userId,name,img));
        } catch (Exception e) {
            e.printStackTrace();
            logger.error(e.getLocalizedMessage());
            return ResultEntity.fail(-10004);
        }
    }

    /**
     * 根据用户id查询用户信息
     *
     * @param userId 用户id
     * @return 返回
     */
    public String getUser(int userId) {
        try {
            return ResultEntity.success(userDao.selectByUserId(userId));
        } catch (Exception e) {
            e.printStackTrace();
            logger.error(e.getLocalizedMessage());
            return ResultEntity.fail(-10004);
        }
    }

}
